﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Linq;

namespace Cloak.Work.NHibernate
{
	/// <summary>
	/// Base class for an abstraction of a set of objects
	/// </summary>
	/// <typeparam name="TEntity">The type of entity contained by the repository</typeparam>
	public abstract class Repository<TEntity>
	{
		/// <summary>
		/// Initializes a repository with the specified session
		/// </summary>
		/// <param name="session">The session which accesses and tracks changes to the data store</param>
		protected Repository(ISession session)
		{
			Contract.Requires(session != null);

			Session = session;
		}

		/// <summary>
		/// Gets the session which accesses and tracks changes to the data store
		/// </summary>
		protected ISession Session { get; private set; }

		/// <summary>
		/// Gets a query over the data store
		/// </summary>
		protected INHibernateQueryable<TEntity> Query
		{
			get { return Session.Linq<TEntity>(); }
		}

		/// <summary>
		/// Gets an untyped query over the data store
		/// </summary>
		protected ICriteria CriteriaQuery
		{
			get { return Session.CreateCriteria(typeof(TEntity)); }
		}

		/// <summary>
		/// Inserts the entity into the data store
		/// </summary>
		/// <param name="entity">The entity to be inserted into the data store</param>
		protected void InsertEntity(TEntity entity)
		{
			Session.Save(entity);
		}

		/// <summary>
		/// Deletes the entity from the data store
		/// </summary>
		/// <param name="entity">The entity to be deleted from the data store</param>
		protected void DeleteEntity(TEntity entity)
		{
			Session.Delete(entity);
		}
	}
}